﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.Extensions.DependencyInjection;
using Syspetro.Core.Extensions;
using System;
using System.Collections.Generic;
using System.Text;

namespace Syspetro.Core.DynamicApi
{
    public static class DynamicApiServiceExtensions
    {
        /// <summary>
        /// Add Dynamic WebApi to Container
        /// </summary>
        /// <param name="services"></param>
        /// <param name="options">configuration</param>
        /// <returns></returns>
        public static IServiceCollection AddDynamicWebApi(this IServiceCollection services, DynamicApiOptions options)
        {
            if (options == null)
            {
                throw new ArgumentException(null, nameof(options));
            }
            options.Valid();
            AppConsts.DefaultAreaName = options.DefaultAreaName;
            AppConsts.DefaultGroupName = options.DefaultGroupName;
            AppConsts.DefaultHttpVerb = options.DefaultHttpVerb;
            AppConsts.DefaultApiPreFix = options.DefaultApiPrefix;
            AppConsts.ControllerPostfixes = options.RemoveControllerPostfixes;
            AppConsts.ActionPostfixes = options.RemoveActionPostfixes;
            AppConsts.FormBodyBindingIgnoredTypes = options.FormBodyBindingIgnoredTypes;
            AppConsts.GetRestFulActionName = options.GetRestFulActionName;
            AppConsts.AssemblyDynamicApiOptions = options.AssemblyDynamicApiOptions;

            var partManager = services.GetSingletonInstanceOrNull<ApplicationPartManager>();

            if (partManager == null)
            {
                throw new InvalidOperationException("\"AddDynamicApi\" must be after \"AddMvc\".");
            }

            partManager.FeatureProviders.Add(new DynamicApiControllerFeatureProvider());

            services.Configure<MvcOptions>(o =>
            {
                o.Conventions.Add(new DynamicApiConvention());
            });

            return services;
        }

        public static IServiceCollection AddDynamicWebApi(this IServiceCollection services, string apiPrefix = "api")
        {
            var option = new DynamicApiOptions();
            if (apiPrefix != string.Empty)
                option.DefaultApiPrefix = apiPrefix;
            return AddDynamicWebApi(services, option);
        }

        public static IServiceCollection AddDynamicWebApi(this IServiceCollection services, Action<DynamicApiOptions> optionsAction)
        {
            var dynamicWebApiOptions = new DynamicApiOptions();

            optionsAction?.Invoke(dynamicWebApiOptions);

            return AddDynamicWebApi(services, dynamicWebApiOptions);
        }
    }
}
